from testudo import Assert
from testudo.framework import SuiteResult, TestResult, FixtureResult, \
	ModuleResult
from testudo.writer_classes import JSONWriter
import testudo.simplejson as json

class JSONWriterTests:
	def test_no_tests(self):
		response = FakeResponse()
		JSONWriter(response).write(SuiteResult())
		result_json = json.loads(response.out.all_responses[0])

		suite_result_json = result_json["suite_result"]
		Assert.is_not_none(suite_result_json)
		Assert.are_equal(0, len(suite_result_json["module_results"]))
		self.assert_statistics(0, 0, 0, 0, 0, suite_result_json)
	
	def test_one_passing_test(self):
		response = FakeResponse()
		test_result = TestResult.create_success("passing_test")
		fixture_result = FixtureResult("test_fixture")
		fixture_result.add_test_result(test_result)
		module_result = ModuleResult("test_module")
		module_result.add_result(fixture_result)
		suite_result = SuiteResult()
		suite_result.add_result(module_result)
		suite_result.total_run_time = 5
		JSONWriter(response).write(suite_result)
		result_json = json.loads(response.out.all_responses[0])
		
		suite_result_json = result_json["suite_result"]
		Assert.is_not_none(suite_result_json, "suite_result_json should not be None.")
		self.assert_statistics(1, 1, 0, 0, 5, suite_result_json)
		
		module_result_json = suite_result_json["module_results"][0]
		Assert.is_not_none(module_result_json, "module_result_json should not be None.")
		Assert.are_equal("test_module", module_result_json["module_name"])
		Assert.are_equal(1, len(module_result_json["fixture_results"]))
		
		fixture_result_json = module_result_json["fixture_results"][0]
		Assert.is_not_none(fixture_result_json, "fixture_result_json should not be None.")
		Assert.are_equal("test_fixture", fixture_result_json["fixture_name"])
		
		test_result_json = fixture_result_json["test_results"][0]
		Assert.is_not_none(test_result_json, "test_result_json should not be None.")
		Assert.are_equal("passing_test", test_result_json["method_name"])
		Assert.is_true(test_result_json["is_successful"], "is_successful should be True.")
		Assert.are_equal("", test_result_json["message"])
		Assert.are_equal("", test_result_json["stack_trace"])
		Assert.is_false(test_result_json["is_ignored"], "is_ignored should be False.")
		
	def assert_statistics(self, expected_total_test_count,  expected_passing_test_count, 
						expected_failing_test_count, expected_ignored_test_count, 
						expected_total_run_time, actual_suite_result_json):
		Assert.are_equal(expected_total_test_count, actual_suite_result_json["total_test_count"], "total count failed.")
		Assert.are_equal(expected_passing_test_count, actual_suite_result_json["passing_test_count"], "passing count failed.")
		Assert.are_equal(expected_failing_test_count, actual_suite_result_json["failing_test_count"], "failing count failed.")
		Assert.are_equal(expected_ignored_test_count, actual_suite_result_json["ignored_test_count"], "ignored count failed.")
		Assert.are_equal(expected_total_run_time, actual_suite_result_json["total_run_time"], "run time failed.")
				
class FakeResponse:
	def __init__(self):
		self.out = MockResponseOut()
	
class MockResponseOut:
	def __init__(self):
		self.all_responses = []
	
	def write(self, output):
		self.all_responses.append(output)
	